package topin.facecat.FaceCat.Service

import facecat.topin.core.FCBinary
import facecat.topin.core.RefObject
import facecat.topin.service.FCClientService
import facecat.topin.service.FCMessage
import topin.facecat.FaceCat.UI.DataCenter
import topin.facecat.FaceCat.UI.MainFrame

/*
 * 历史数据服务
 */
class HistoryServiceClient : FCClientService() {
    //获取代码
    var FUNCTIONID_GETCODE = 1

    //获取复权因子
    var FUNCTIONID_GETDR = 2

    /*
     * 获取套接字
     */
    var socketID = 0

    init {
        serviceID = SERVICEID
    }

    /*
     * 请求代码
     *@param requestID 请求ID
     */
    fun reqCodes(requestID: Int) {
        val bw = FCBinary()
        try {
            bw.writeString("1")
            val bytes = bw.bytes
            bw.close()
            val ret = send(
                FCMessage(
                    serviceID, FUNCTIONID_GETCODE, requestID,
                    socketID, 0, compressType, bytes.size, bytes
                )
            )
        } catch (ex: Exception) {
        }
    }

    /*
     * 请求数据
     *@param request_ID 请求ID
     *@param code 代码
     *@param cycle 周期
     *@param startDate 开始日期
     *@param endDate 结束日期
     */
    fun reqData(
        requestID: Int,
        code: String?,
        cycle: Int,
        subscription: Int,
        startDate: Double,
        endDate: Double
    ) {
        val bw = FCBinary()
        try {
            bw.writeString(code)
            bw.writeInt(cycle)
            bw.writeDouble(startDate)
            bw.writeDouble(endDate)
            bw.writeInt(subscription)
            val bytes = bw.bytes
            bw.close()
            val ret = send(
                FCMessage(
                    serviceID, FUNCTIONID_GETDATA, requestID,
                    socketID, 0, compressType, bytes.size, bytes
                )
            )
        } catch (ex: Exception) {
        }
    }

    /*
     * 请求数据
     *@param request_ID
     *@param code
     *@param oldRequestID
     */
    fun reqData2(requestID: Int, code: String?, oldRequestID: Int) {
        val bw = FCBinary()
        try {
            bw.writeString(code)
            bw.writeInt(oldRequestID)
            val bytes = bw.bytes
            bw.close()
            val ret = send(
                FCMessage(
                    serviceID, FUNCTIONID_GETDATA2, requestID,
                    socketID, 0, compressType, bytes.size, bytes
                )
            )
        } catch (ex: Exception) {
        }
    }

    /*
     * 请求复权因子
     */
    fun reqDevideDatas(requestID: Int) {
        val bw = FCBinary()
        try {
            bw.writeInt(0)
            val bytes = bw.bytes
            bw.close()
            val ret = send(
                FCMessage(
                    serviceID, FUNCTIONID_GETDR, requestID,
                    socketID, 0, 0, bytes.size, bytes
                )
            )
        } catch (ex: Exception) {
        }
    }

    /*
     * 解析复权因子
     *@param body
     *@param bodyLength
     */
    fun getFactors(
        body: ByteArray?,
        bodyLength: Int
    ): HashMap<String, ArrayList<ADJUSTMENTFACTOR>>? {
        val factors = HashMap<String, ArrayList<ADJUSTMENTFACTOR>>()
        val br = FCBinary()
        return try {
            br.write(body, bodyLength)
            val size = br.readInt()
            for (i in 0 until size) {
                val code = br.readString()
                val dfSize = br.readInt()
                val aList = ArrayList<ADJUSTMENTFACTOR>()
                for (j in 0 until dfSize) {
                    val af = ADJUSTMENTFACTOR()
                    af.dwDate = br.readInt().toDouble() * 86400
                    af.f1 = br.readFloat()
                    af.f2 = br.readFloat()
                    af.f3 = br.readFloat()
                    af.f4 = br.readFloat()
                    aList.add(af)
                }
                factors[code] = aList
            }
            br.close()
            factors
        } catch (ex: Exception) {
            null
        }
    }

    /*
     * 接受消息方法
     */
    override fun onReceive(message: FCMessage) {
        super.onReceive(message)
        if (message.m_functionID == FUNCTIONID_GETCODE) {
            val securities = getCodes(message.m_body, message.m_bodyLength)
            DataCenter.m_securityService!!.load(securities!!)
        } else if (message.m_functionID == FUNCTIONID_GETDR) {
            StockService.m_factors = getFactors(message.m_body, message.m_bodyLength)!!
        }else {
            MainFrame.m_mainFrame.m_tabFunc!!.beginInvoke(message);
        }
        //sendToListener(message)
    }

    companion object {
        var SERVICEID = 10001

        //获取数据
        var FUNCTIONID_GETDATA = 0

        //获取数据
        var FUNCTIONID_GETDATA2 = 3

        /*
         * 获取数据
         *@param code 代码
         *@param cycle 周期
         *@param startDate 开始日期
         *@param endDate 结束日期
         *@param nowDate 当前日期
         *@param nowVolume 当前成交量
         *@param nowAmount 当前成交额
         *@param body 包体
         *@param bodyLength 包体长度
         */
        fun getDatas(
            refCode: RefObject<String>,
            refCycle: RefObject<Int>,
            refStartDate: RefObject<Double>,
            refEndDate: RefObject<Double>,
            refSubscription: RefObject<Int>,
            refNowDate: RefObject<Double>,
            refNowVolume: RefObject<Double>,
            refNowAmount: RefObject<Double>,
            body: ByteArray?,
            bodyLength: Int
        ): ArrayList<SecurityData>? {
            val br = FCBinary()
            return try {
                br.write(body, bodyLength)
                refCode.argvalue = br.readString()
                refCycle.argvalue = br.readInt()
                refStartDate.argvalue = br.readDouble()
                refEndDate.argvalue = br.readDouble()
                refSubscription.argvalue = br.readInt()
                refNowDate.argvalue = br.readDouble()
                refNowVolume.argvalue = br.readDouble()
                refNowAmount.argvalue = br.readDouble()
                val code = refCode.argvalue
                val cycle = refCycle.argvalue
                val startDate = refStartDate.argvalue
                val endDate = refEndDate.argvalue
                val subscription = refSubscription.argvalue
                val nowDate = refNowDate.argvalue
                val nowVolume = refNowVolume.argvalue
                val nowAmount = refNowAmount.argvalue
                val datasSize = br.readInt()
                val datas = ArrayList<SecurityData>()
                val seDate = cycle != 0 && cycle != 1 && cycle != 1440
                for (i in 0 until datasSize) {
                    val data = SecurityData()
                    if (cycle >= 1440) {
                        data.m_date = (br.readShort() * 86400).toDouble()
                    } else {
                        data.m_date = (br.readInt() * 60).toDouble()
                    }
                    data.m_close = br.readDouble()
                    data.m_high = br.readDouble()
                    data.m_low = br.readDouble()
                    data.m_open = br.readDouble()
                    val type = br.readByte().toInt()
                    if (type == 0) {
                        data.m_volume = br.readDouble()
                        data.m_amount = br.readDouble()
                    } else {
                        data.m_volume = br.readInt().toDouble()
                        data.m_amount = br.readInt().toDouble()
                    }
                    if (seDate) {
                        if (cycle >= 1440) {
                            data.m_startDate = (br.readShort() * 86400).toDouble()
                            data.m_endDate = (br.readShort() * 86400).toDouble()
                        } else {
                            data.m_startDate = (br.readInt() * 60).toDouble()
                            data.m_endDate = (br.readInt() * 60).toDouble()
                        }
                    }
                    if (cycle > 0 && data.m_volume == 0.0) {
                        continue
                    }
                    datas.add(data)
                }
                br.close()
                datas
            } catch (ex: Exception) {
                null
            }
        }

        fun getDatas2(
            code: RefObject<String?>,
            dayDatas: ArrayList<SecurityData>?,
            minuteDatas: ArrayList<SecurityData>?,
            trendDatas: ArrayList<SecurityData>?,
            body: ByteArray?,
            bodyLength: Int
        ) {
//        传入一个对象，修改对象的值，再函数外使用
            val br = FCBinary()
            try {
                br.write(body, bodyLength)
                code.argvalue = br.readString()
                var datas: ArrayList<SecurityData>? = null
                for (d in 0..2) {
                    datas = if (d == 0) {
                        dayDatas
                    } else if (d == 1) {
                        minuteDatas
                    } else {
                        trendDatas
                    }
                    val datasSize = br.readInt()
                    for (i in 0 until datasSize) {
                        val data = SecurityData()
                        if (d == 0) {
                            data.m_date = (br.readShort() * 86400).toDouble()
                        } else {
                            data.m_date = (br.readInt() * 60).toDouble()
                        }
                        val type2 = br.readByte().toInt()
                        if (type2 == 1) {
                            data.m_close = br.readShort().toDouble() / 100
                            data.m_high = br.readShort().toDouble() / 100
                            data.m_low = br.readShort().toDouble() / 100
                            data.m_open = br.readShort().toDouble() / 100
                        } else {
                            data.m_close = br.readDouble()
                            data.m_high = br.readDouble()
                            data.m_low = br.readDouble()
                            data.m_open = br.readDouble()
                        }
                        val type = br.readByte().toInt()
                        if (type == 0) {
                            data.m_volume = br.readDouble()
                            data.m_amount = br.readDouble()
                        } else {
                            data.m_volume = br.readInt().toDouble()
                            data.m_amount = br.readInt().toDouble()
                        }
                        if (d < 2 && data.m_volume == 0.0) {
                            continue
                        }
                        datas!!.add(data)
                    }
                }
                br.close()
            } catch (ex: Exception) {
            }
        }

        /*
         * 获取代码
         *param body 包体
         *param bodyLength 包头长度
         */
        fun getCodes(body: ByteArray?, bodyLength: Int): ArrayList<Security>? {
            val br = FCBinary()
            return try {
                br.write(body, bodyLength)
                val datasSize = br.readInt()
                val datas = ArrayList<Security>()
                for (i in 0 until datasSize) {
                    val security = Security()
                    security.m_code = br.readString()
                    security.m_name = br.readString()
                    security.m_pingyin = br.readString()
                    security.m_type = br.readByte().toInt()
                    security.m_block = br.readString()
                    datas.add(security)
                }
                br.close()
                datas
            } catch (ex: Exception) {
                null
            }
        }
    }
}





